import { createFileRoute, redirect } from "@tanstack/react-router";
import { Loader2Icon, MailIcon } from "lucide-react";
import * as React from "react";
import { GridPattern } from "@/components/background/grid";
import { Icons } from "@/components/icons";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { authClient } from "@/lib/auth-client";
import { cn } from "@/lib/utils";
import { sessionQueryOptions } from "@/queries/auth";

export const Route = createFileRoute("/login")({
  beforeLoad: async ({ context: { queryClient } }) => {
    const session = await queryClient.ensureQueryData(sessionQueryOptions);
    if (session) throw redirect({ to: "/" });
    return { session };
  },
  component: LoginPage,
});

function LoginPage() {
  const [email, setEmail] = React.useState("");
  const [otp, setOtp] = React.useState("");
  const [step, setStep] = React.useState<"inputEmail" | "inputOtp">("inputEmail");
  const [loading, setLoading] = React.useState(false);
  const [countdown, setCountdown] = React.useState(0);
  const [error, setError] = React.useState("");

  React.useEffect(() => {
    if (countdown <= 0) return;
    const t = setInterval(() => setCountdown((c) => c - 1), 1000);
    return () => clearInterval(t);
  }, [countdown]);

  const sendOtp = async () => {
    if (!email) return setError("please enter your email");
    setLoading(true);
    setError("");
    const { error } = await authClient.emailOtp.sendVerificationOtp({
      email,
      type: "sign-in",
    });
    setLoading(false);
    if (error) return setError(error.message ?? "something went wrong");
    setStep("inputOtp");
    setCountdown(30);
  };

  const verifyOtp = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!otp) return setError("input a valid otp");
    setLoading(true);
    setError("");
    const { error } = await authClient.signIn.emailOtp({ email, otp });
    setLoading(false);
    if (error) return setError(error.message ?? "otp verification failed");
    window.location.href = "/";
  };

  return (
    <div className="flex min-h-svh flex-col items-center justify-center p-6 md:p-8">
      <GridPattern
        width={20}
        height={20}
        x={-1}
        y={-1}
        className={cn(
          "[mask-image:linear-gradient(to_bottom_right,white,transparent,transparent)] ",
        )}
      />
      <div className="w-full max-w-sm md:max-w-md">
        <div className="flex flex-col items-center justify-center gap-6">
          <Card className="w-3xl overflow-hidden p-0">
            <CardContent className="grid p-0 md:grid-cols-2">
              <div className="hidden flex-col items-center justify-center bg-secondary md:flex">
                <svg
                  viewBox="438 413 323 375"
                  xmlns="http://www.w3.org/2000/svg"
                  className="h-1/2 w-1/2 fill-primary"
                >
                  <path
                    d="M728.494 566.349V565.392L635.796 618.817L635.483 618.973V725.98L728.351 672.321L728.494 566.349ZM727.207 671.662L636.595 723.959V619.606L727.284 567.39L727.207 671.662Z"
                    fill="fill-primary"
                  />
                  <path
                    d="M760.055 506.494L599.074 413L438 506.668L438.235 506.825L438.251 525.057L453.91 515.91L470.133 525.308L438.235 543.869V562.258L485.95 534.456L502.503 544.011L438.317 581.369V599.852L469.901 581.291V566.354L482.751 573.744L518.335 553.017L534.559 562.416L498.974 583.142L514.806 592.305L550.313 571.578L566.787 581.134L531.203 601.86L547.035 611.023L582.542 590.297L598.844 599.695L561.643 621.3V639.689L598.924 617.912V637.038L561.643 658.721V677.11L598.924 655.333V674.208L561.643 695.891V714.28L598.924 692.503V711.143L590.577 715.96L535.301 748.093L535.379 748.171L551.211 757.334L598.925 729.453V748.249L567.357 766.638L583.267 775.801L598.925 766.638V786L760.957 692.332L761.192 506.609V505.652L760.055 506.494ZM507.414 505.867L599.232 452.442L691.534 506.024L639.96 535.741L599.556 558.962L507.414 505.867ZM759.978 691.744L600.209 784.046V599.846L760.232 507.701L759.978 691.744Z"
                    fill="fill-primary"
                  />
                  <path
                    d="M469.986 618.488L469.907 600.005L438.418 618.331L438.496 636.799L469.986 618.488Z"
                    fill="fill-primary"
                  />
                  <path
                    d="M469.986 637.444L438.496 655.754V674.237L469.986 655.926V637.444Z"
                    fill="fill-primary"
                  />
                  <path
                    d="M472.232 673.279L439.22 692.468L455.208 701.709L488.22 682.504L472.232 673.279Z"
                    fill="fill-primary"
                  />
                  <path
                    d="M504.536 691.903L471.508 711.107L487.496 720.349L520.43 701.144L504.536 691.903Z"
                    fill="fill-primary"
                  />
                  <path
                    d="M536.575 710.463L503.563 729.667L519.473 738.909L552.485 719.626L536.575 710.463Z"
                    fill="fill-primary"
                  />
                </svg>
              </div>
              <div className="flex flex-col gap-4 p-6 md:p-8">
                <form onSubmit={step === "inputEmail" ? undefined : verifyOtp}>
                  <div className="flex flex-col gap-6">
                    <h1 className="text-center font-semibold text-2xl">Welcome back</h1>
                    <div className="*:not-first:mt-2">
                      <Input
                        id="email"
                        placeholder="example@example.com"
                        type="email"
                        value={email}
                        onChange={(e) => setEmail(e.target.value)}
                        disabled={step === "inputOtp"}
                        required
                        aria-invalid={error ? "true" : "false"}
                      />
                    </div>
                    <div className="flex rounded-md shadow-xs">
                      <Input
                        id="opt"
                        maxLength={6}
                        value={otp}
                        onChange={(e) => setOtp(e.target.value)}
                        className="-me-px flex-1 rounded-e-none shadow-none focus-visible:z-10"
                        placeholder="opt"
                        required
                      />
                      <button
                        type="button"
                        onClick={sendOtp}
                        disabled={countdown > 0 || loading}
                        className="inline-flex items-center rounded-e-md border border-input bg-background px-3 font-medium text-foreground text-sm outline-none transition-[color,box-shadow] hover:bg-accent hover:text-foreground focus:z-10 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50"
                      >
                        {countdown > 0 ? countdown : <MailIcon size={16} aria-hidden="true" />}
                      </button>
                    </div>
                    <div className="flex flex-col gap-2">
                      {error && <p className="text-destructive text-xs">{error}</p>}
                      <Button type="submit" className="w-full" disabled={loading}>
                        {loading && <Loader2Icon className="animate-spin" />}
                        Login
                      </Button>
                    </div>
                    <div className="relative text-center text-sm after:absolute after:inset-0 after:top-1/2 after:z-0 after:flex after:items-center after:border-border after:border-t">
                      <span className="relative z-10 bg-card px-2 text-muted-foreground">OR</span>
                    </div>
                  </div>
                </form>
                <div className="flex w-full flex-col gap-2">
                  <Button
                    variant="outline"
                    type="button"
                    className="w-full"
                    onClick={async () => {
                      await authClient.signIn.social({
                        provider: "github",
                        callbackURL: import.meta.env.VITE_WEB_URL,
                      });
                    }}
                  >
                    <Icons.gitHub className="size-4" />
                    <p className="text-sm">Continue with Github</p>
                    <span className="sr-only">Continue with Github</span>
                  </Button>
                </div>
              </div>
            </CardContent>
          </Card>
          <div className="text-balance text-center text-muted-foreground text-xs *:[a]:underline *:[a]:underline-offset-4 *:[a]:hover:text-primary">
            By login continue, you agree to our <a href="/">Terms of Service</a> and{" "}
            <a href="/">Privacy Policy</a>.
          </div>
        </div>
      </div>
    </div>
  );
}
